#include "qls_ruler.h"

#include <cmath>

#include <QPainter>
#include <QMouseEvent>
#include <QtMath>
#include <QToolTip>
#include <QLabel>
#include <QMap>

QLsRuler::QLsRuler(QWidget *parent) : QWidget(parent)
{
    // 游标旁提示值
    cursor_label_ = new QLabel(this);
    cursor_label_->setFixedSize(40, 20);
    cursor_label_->setAlignment(Qt::AlignCenter);
    cursor_label_->hide();

    // 内边距
    padding_top_ = 5;
    padding_right_ = 5;
    padding_bottom_ = 5;
    padding_left_ = 5;
    // 文字到刻度条的间距
    scale_label_space_ = 5;

    // 标尺类型
    ruler_type_ = RulerType_Cursor;
    connect(this, &QLsRuler::sig_ruler_type_changed, [=]{
        switch (get_ruler_type_()) {
        case RulerType_Scale:
            cursor_visiable_ = false;
            scale_label_visiable_ = false;
            break;
        case RulerType_Cursor:
            cursor_visiable_ = true;
            scale_label_visiable_ = true;
            break;
        case RulerType_Line:
            cursor_visiable_ = false;
            scale_label_visiable_ = true;
            break;
        case RulerType_Progress:
            cursor_visiable_ = false;
            scale_label_visiable_ = true;
            break;
        case RulerType_Slide:
            cursor_visiable_ = true;
            scale_label_visiable_ = true;
            break;
        }
    });

    // 标尺方向
    ruler_direction_ = RulerDirection_West;
    // 刻度方向
    scale_direction_ = ScaleDirection_Left_To_Right;

    // 刻度值
    scale_value_ = 20;
    scale_unit_value_ = 3;
    scale_label_value_ = 1;
    // 刻度类型
    scale_type_ = ScaleType_Number;

    // 刻度范围
    scale_range_all_min_ = 0;
    scale_range_all_max_ = 100;
    scale_range_valid_enabled_ = true;
    scale_range_valid_min_ = 0;
    scale_range_valid_max_ = 100;
    // 刻度条范围颜色
    scale_range_all_color_ = QColor(204, 204, 204);
    scale_range_valid_color_ = QColor(129 , 126, 121);
    // 刻度条范围背景颜色
    scale_range_all_bgcolor_ = QColor(238, 238, 238);
    scale_range_valid_bgcolor_ = QColor(0, 255, 0);

    // 刻度条尺寸
    scale_unit_size_ = QSize(3, 5);
    scale_label_size_ = QSize(3, 10);
    // 刻度条厚度
    scale_thickness_ = 3;

    // 刻度值标签位置
    scale_label_position_ = ScaleLabelPosition_Outside;

    // 是否显示游标
    cursor_visiable_ = true;
    // 游标颜色
    cursor_color_ = QColor(255, 129, 0);
    // 游标边长
    cursor_side_ = 15;
    // 是否显示游标提示值
    cursor_label_visiable_ = false;
}

void QLsRuler::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);    // 反锯齿

    drawProgress(&painter);
    drawScaleRangeColor(&painter);
    drawScale(&painter);
    drawLabel(&painter);
    drawLine(&painter);
    drawCursor(&painter);

    updateMinimumSize(&painter);

    QWidget::paintEvent(event);
}

void QLsRuler::mousePressEvent(QMouseEvent *event)
{
    press_ = true;

    // 按下游标，记录当前坐标，进入拖拽状态
    if(get_ruler_type_() == RulerType_Slide &&
            triangle_.containsPoint(
                getRotatePoint(
                    translate_point_, event->pos(), rotate_angle_
                    ), Qt::OddEvenFill)){
        triangle_pos_ = event->pos();
        is_move_triangle_ = true;

        // 游标旁显示当前值
        if(cursor_label_visiable_ && cursor_label_->isHidden()){
            cursor_label_->show();
            cursor_label_->setText(QString::number(get_scale_value_(), 'f', 0));
            if(event->pos().x() + 10 + cursor_label_->width() >= width()){
                cursor_label_->move(event->pos() - QPoint(-cursor_label_->width() - 10, 0));
            } else {
                cursor_label_->move(event->pos() + QPoint(10, 0));
            }
        }
    }

    update();
    QWidget::mousePressEvent(event);
}

void QLsRuler::mouseReleaseEvent(QMouseEvent *event)
{
    press_ = false;
    is_move_triangle_ = false;

    // 隐藏游标提示值
    if(cursor_label_visiable_ && cursor_label_->isVisible()){
        cursor_label_->hide();
    }

    update();
    QWidget::mouseReleaseEvent(event);
}

void QLsRuler::mouseMoveEvent(QMouseEvent *event)
{
    // 拖拽
    if(is_move_triangle_){
        // 横向推拽
        if(get_ruler_direction_() == RulerDirection_West || get_ruler_direction_() == RulerDirection_South){
            double x = event->pos().x() - triangle_pos_.x();
            QPainter painter(this);
            scale_value_ = get_scale_value_() +
                    (get_ruler_direction_() == RulerDirection_West ||
                     get_ruler_direction_() == RulerDirection_North ? 1.0 : -1.0) *
                    (get_scale_direction_() == ScaleDirection_Left_To_Right ? 1.0 : -1.0) *
                    x * (get_scale_range_all_max_() - get_scale_range_all_min_()) /
                    getRotateRectScale(&painter).width();
        }
        // 竖向拖拽
        else {
            double y = event->pos().y() - triangle_pos_.y();
            QPainter painter(this);
            scale_value_ = get_scale_value_() +
                    (get_ruler_direction_() == RulerDirection_West ||
                     get_ruler_direction_() == RulerDirection_North ? 1.0 : -1.0) *
                    (get_scale_direction_() == ScaleDirection_Left_To_Right ? 1.0 : -1.0) *
                    y * (get_scale_range_all_max_() - get_scale_range_all_min_()) /
                    getRotateRectScale(&painter).width();
        }
        // 记录上次坐标
        triangle_pos_ = event->pos();

        // 游标旁显示当前值
        if(cursor_label_visiable_ && cursor_label_->isVisible()){
            cursor_label_->setText(QString::number(get_scale_value_(), 'f', 0));
            if(event->pos().x() + 10 + cursor_label_->width() >= width()){
                cursor_label_->move(event->pos() - QPoint(cursor_label_->width() + 10, 0));
            } else {
                cursor_label_->move(event->pos() + QPoint(10, 0));
            }
        }

        // 更新游标
        update();
        return;
    }

    QWidget::mouseMoveEvent(event);
}

void QLsRuler::updateMinimumSize(QPainter *painter)
{
    painter->save();
    switch (get_ruler_direction_()) {
    case RulerDirection_West:
    case RulerDirection_South:
        setMinimumWidth(0);
        setMinimumHeight(getRotateRectTrue(painter).adjusted(
                             -get_padding_left_(), -get_padding_top_(),
                             get_padding_right_(), get_padding_bottom_()).height());
        break;
    case RulerDirection_East:
    case RulerDirection_North:
        setMinimumHeight(0);
        setMinimumWidth(getRotateRectTrue(painter).adjusted(
                            -get_padding_left_(), -get_padding_top_(),
                            get_padding_right_(), get_padding_bottom_()).width());
        break;
    default: break;
    }
    painter->restore();
}

void QLsRuler::drawProgress(QPainter *painter)
{
    if(get_ruler_type_() != RulerType_Progress){
        return;
    }

    painter->save();
    painter->setPen(Qt::NoPen);

    QRect rect_all = getRotateRectAll(painter);

    // 从左到右
    if(get_scale_direction_() == ScaleDirection_Left_To_Right){
        // 绘制刻度条整体背景颜色
        painter->setBrush(get_scale_range_all_bgcolor_());
        painter->drawRect(rect_all.adjusted(rect_all.width() * get_scale_value_() / (get_scale_range_all_max_() - get_scale_range_all_min_()), 0, 0, 0));

        // 绘制刻度条有效背景颜色
        painter->setBrush(get_scale_range_valid_bgcolor_());
        painter->drawRect(rect_all.adjusted(0, 0, -rect_all.width() * (1 - get_scale_value_() / (get_scale_range_all_max_() - get_scale_range_all_min_())), 0));
    }
    // 从右到左
    else {
        // 绘制刻度条整体背景颜色
        painter->setBrush(get_scale_range_all_bgcolor_());
        painter->drawRect(rect_all.adjusted(0, 0, -rect_all.width() * get_scale_value_() / (get_scale_range_all_max_() - get_scale_range_all_min_()), 0));

        // 绘制刻度条有效背景颜色
        painter->setBrush(get_scale_range_valid_bgcolor_());
        painter->drawRect(rect_all.adjusted(rect_all.width() * (1 - get_scale_value_() / (get_scale_range_all_max_() - get_scale_range_all_min_())), 0, 0, 0));
    }

    painter->restore();
}

void QLsRuler::drawScaleRangeColor(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);

    QRect rect_scale = getRotateRectScale(painter);

    // 绘制刻度条整体颜色
    painter->setBrush(get_scale_range_all_color_());
    painter->drawRect(rect_scale.adjusted(0, rect_scale.height() - get_scale_thickness_(), 0, 0));

    painter->setBrush(get_scale_range_valid_color_());
    // 从左到右
    if(get_scale_direction_() == ScaleDirection_Left_To_Right) {
        // 绘制刻度条有效颜色
        painter->drawRect(
                    rect_scale.adjusted(
                        rect_scale.width() * (get_scale_range_valid_min_() - get_scale_range_all_min_()) /
                        (get_scale_range_all_max_() - get_scale_range_all_min_()),
                        rect_scale.height() - get_scale_thickness_(),
                        -rect_scale.width() * (get_scale_range_all_max_() - get_scale_range_valid_max_()) /
                        (get_scale_range_all_max_() - get_scale_range_all_min_()),
                        0));
    }
    // 从右到左
    else {
        // 绘制刻度条有效颜色
        painter->drawRect(
                    rect_scale.adjusted(
                        rect_scale.width() * (get_scale_range_all_max_() - get_scale_range_valid_max_()) /
                        (get_scale_range_all_max_() - get_scale_range_all_min_()),
                        rect_scale.height() - get_scale_thickness_(),
                        -rect_scale.width() * (get_scale_range_valid_min_() - get_scale_range_all_min_()) /
                        (get_scale_range_all_max_() - get_scale_range_all_min_()),
                        0));

    }

    painter->restore();
}

void QLsRuler::drawScale(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(get_scale_range_all_color_());

    QRect rect_scale = getRotateRectScale(painter);

    // 绘制刻度
    // 绘制两侧刻度
    painter->drawRect(rect_scale.left() - get_scale_label_size_().width() / 2, rect_scale.top(), get_scale_label_size_().width(), get_scale_label_size_().height());
    painter->drawRect(rect_scale.right() - get_scale_label_size_().width() / 2, rect_scale.top(),
                      get_scale_label_size_().width(), get_scale_label_size_().height());

    // 根据刻度值绘制
    if(get_scale_type_() == ScaleType_Value){
        // 从左到右
        if(get_scale_direction_() == ScaleDirection_Left_To_Right){
            for(int i = get_scale_range_all_min_() + get_scale_unit_value_();
                i < get_scale_range_all_max_(); i += get_scale_unit_value_()){
                // 绘制标签刻度
                if(i % QString::number(get_scale_label_value_()).toInt() == 0){
                    painter->drawRect(rect_scale.left() + rect_scale.width() *
                                      (i - get_scale_range_all_min_()) /
                                      (get_scale_range_all_max_() - get_scale_range_all_min_())
                                      - get_scale_label_size_().width() / 2,
                                      rect_scale.top(),
                                      get_scale_label_size_().width(), get_scale_label_size_().height());
                }
                // 绘制单位刻度
                else if(i % QString::number(get_scale_unit_value_()).toInt() == 0) {
                    painter->drawRect(rect_scale.left() + rect_scale.width() *
                                      (i - get_scale_range_all_min_()) /
                                      (get_scale_range_all_max_() - get_scale_range_all_min_())
                                      - get_scale_unit_size_().width() / 2,
                                      rect_scale.top() + get_scale_label_size_().height() - get_scale_unit_size_().height(),
                                      get_scale_unit_size_().width(), get_scale_unit_size_().height());
                }
            }
        }
        // 从右到左
        else {
            for(int i = get_scale_range_all_min_() + get_scale_unit_value_();
                i < get_scale_range_all_max_(); i += get_scale_unit_value_()){
                // 绘制标签刻度
                if(i % QString::number(get_scale_label_value_()).toInt() == 0){
                    painter->drawRect(rect_scale.left() + rect_scale.width() *
                                      (get_scale_range_all_max_() - i) /
                                      (get_scale_range_all_max_() - get_scale_range_all_min_())
                                      - get_scale_label_size_().width() / 2,
                                      rect_scale.top(),
                                      get_scale_label_size_().width(), get_scale_label_size_().height());
                }
                // 绘制单位刻度
                else if(i % QString::number(get_scale_unit_value_()).toInt() == 0) {
                    painter->drawRect(rect_scale.left() + rect_scale.width() *
                                      (get_scale_range_all_max_() - i) /
                                      (get_scale_range_all_max_() - get_scale_range_all_min_())
                                      - get_scale_unit_size_().width() / 2,
                                      rect_scale.top() + get_scale_label_size_().height() - get_scale_unit_size_().height(),
                                      get_scale_unit_size_().width(), get_scale_unit_size_().height());
                }
            }
        }
    }
    // 根据刻度个数绘制
    else {
        // 从左到右
        if(get_scale_direction_() == ScaleDirection_Left_To_Right){
            auto num = get_scale_unit_value_() * (get_scale_label_value_() + 1) + get_scale_label_value_();
            auto unit_val = (get_scale_range_all_max_() - get_scale_range_all_min_()) / (num + 1);
            for(int index = 1; index <= num; index++){
                auto i = index * unit_val + get_scale_range_all_min_();
                // 绘制标签刻度
                if(index % (QString::number(get_scale_unit_value_()).toInt() + 1) == 0){
                    painter->drawRect(rect_scale.left() + rect_scale.width() *
                                      (i - get_scale_range_all_min_()) /
                                      (get_scale_range_all_max_() - get_scale_range_all_min_())
                                      - get_scale_label_size_().width() / 2,
                                      rect_scale.top(),
                                      get_scale_label_size_().width(), get_scale_label_size_().height());
                }
                // 绘制单位刻度
                else {
                    painter->drawRect(rect_scale.left() + rect_scale.width() *
                                      (i - get_scale_range_all_min_()) /
                                      (get_scale_range_all_max_() - get_scale_range_all_min_())
                                      - get_scale_unit_size_().width() / 2,
                                      rect_scale.top() + get_scale_label_size_().height() - get_scale_unit_size_().height(),
                                      get_scale_unit_size_().width(), get_scale_unit_size_().height());
                }
            }
        }
        // 从右到左
        else {
            auto num = get_scale_unit_value_() * (get_scale_label_value_() + 1) + get_scale_label_value_();
            auto unit_val = (get_scale_range_all_max_() - get_scale_range_all_min_()) / (num + 1);
            for(int index = 1; index <= num; index++){
                auto i = index * unit_val + get_scale_range_all_min_();
                // 绘制标签刻度
                if(index % (QString::number(get_scale_unit_value_()).toInt() + 1) == 0){
                    painter->drawRect(rect_scale.left() + rect_scale.width() *
                                      (get_scale_range_all_max_() - i) /
                                      (get_scale_range_all_max_() - get_scale_range_all_min_())
                                      - get_scale_label_size_().width() / 2,
                                      rect_scale.top(),
                                      get_scale_label_size_().width(), get_scale_label_size_().height());
                }
                // 绘制单位刻度
                else {
                    painter->drawRect(rect_scale.left() + rect_scale.width() *
                                      (get_scale_range_all_max_() - i) /
                                      (get_scale_range_all_max_() - get_scale_range_all_min_())
                                      - get_scale_unit_size_().width() / 2,
                                      rect_scale.top() + get_scale_label_size_().height() - get_scale_unit_size_().height(),
                                      get_scale_unit_size_().width(), get_scale_unit_size_().height());
                }
            }
        }
    }

    painter->restore();
}

bool operator<(const QPointF &p1, const QPointF &p2){
    return p1.x() == p2.x() ? p1.y() < p2.y() : p1.x() < p2.x();
}

void QLsRuler::drawLabel(QPainter *painter)
{
    if(!get_scale_label_visiable_()){
        return;
    }

    painter->save();

    QRect rect_label = getRotateRectLabel(painter);
    QFontMetrics fm(font());
    QMap<QPointF, QString> map_label_points;
    QPointF left_point, right_point;

    // 根据刻度值绘制
    if(get_scale_type_() == ScaleType_Value){
        // 从左到右
        if(get_scale_direction_() == ScaleDirection_Left_To_Right){
            // 绘制两侧标签
            QString str_min = QString::number(get_scale_range_all_min_(), 'f', 0);
            map_label_points.insert(left_point = QPointF(rect_label.left(), rect_label.bottom()), str_min);
            QString str_max = QString::number(get_scale_range_all_max_(), 'f', 0);
            map_label_points.insert(right_point = QPointF(rect_label.right() - fm.horizontalAdvance(str_max),
                                            rect_label.bottom()), str_max);

            // 绘制标签
            auto label_pix = rect_label.width() / ((get_scale_range_all_max_() - get_scale_range_all_min_()) /
                                                         get_scale_label_value_());
            for(int i = get_scale_range_all_min_() + get_scale_unit_value_();
                i < get_scale_range_all_max_(); i += get_scale_unit_value_()){
                if(i % QString::number(get_scale_label_value_()).toInt()){
                    continue;
                }

                auto index = (i - get_scale_range_all_min_()) / get_scale_label_value_();
                QString str_i = QString::number(i, 'f', 0);
                map_label_points.insert(QPointF(rect_label.left() + index * label_pix - fm.horizontalAdvance(str_i) / 2,
                                                rect_label.bottom()), str_i);
            }
        }
        // 从右到左
        else {
            // 绘制两侧标签
            QString str_max = QString::number(get_scale_range_all_max_(), 'f', 0);
            map_label_points.insert(left_point = QPointF(rect_label.left(), rect_label.bottom()), str_max);
            QString str_min = QString::number(get_scale_range_all_min_(), 'f', 0);
            map_label_points.insert(right_point = QPointF(rect_label.right() - fm.horizontalAdvance(str_min),
                                            rect_label.bottom()), str_min);

            // 绘制标签
            auto label_pix = rect_label.width() / ((get_scale_range_all_max_() - get_scale_range_all_min_()) /
                                                         get_scale_label_value_());
            for(int i = get_scale_range_all_min_() + get_scale_unit_value_();
                i < get_scale_range_all_max_(); i += get_scale_unit_value_()){
                if(i % QString::number(get_scale_label_value_()).toInt()){
                    continue;
                }

                auto index = (i - get_scale_range_all_min_()) / get_scale_label_value_();
                QString str_i = QString::number(i, 'f', 0);
                map_label_points.insert(QPointF(rect_label.right() - index * label_pix - fm.horizontalAdvance(str_i) / 2,
                                                rect_label.bottom()), str_i);
            }
        }
    }
    // 根据刻度个数绘制
    else {
        // 从左到右
        if(get_scale_direction_() == ScaleDirection_Left_To_Right){
            // 绘制两侧标签
            QString str_min = QString::number(get_scale_range_all_min_(), 'f', 0);
            map_label_points.insert(left_point = QPointF(rect_label.left(), rect_label.bottom()), str_min);
            QString str_max = QString::number(get_scale_range_all_max_(), 'f', 0);
            map_label_points.insert(right_point = QPointF(rect_label.right() - fm.horizontalAdvance(str_max),
                                            rect_label.bottom()), str_max);

            // 绘制标签
            auto label_pix = rect_label.width() / (get_scale_label_value_() + 1);
            auto label_value_unit = (get_scale_range_all_max_() - get_scale_range_all_min_()) / (get_scale_label_value_() + 1);
            for(int i = 1; i <= get_scale_label_value_(); i++){
                QString str_i = QString::number(i * label_value_unit + get_scale_range_all_min_(), 'f', 0);
                map_label_points.insert(QPointF(rect_label.left() + i * label_pix -
                                                fm.horizontalAdvance(str_i) / 2,
                                            rect_label.bottom()), str_i);
            }
        }
        // 从右到左
        else {
            // 绘制两侧标签
            QString str_max = QString::number(get_scale_range_all_max_(), 'f', 0);
            map_label_points.insert(left_point = QPointF(rect_label.left(), rect_label.bottom()), str_max);
            QString str_min = QString::number(get_scale_range_all_min_(), 'f', 0);
            map_label_points.insert(right_point = QPointF(rect_label.right() - fm.horizontalAdvance(str_min),
                                            rect_label.bottom()), str_min);

            // 绘制标签
            auto label_pix = rect_label.width() / (get_scale_label_value_() + 1);
            auto label_value_unit = (get_scale_range_all_max_() - get_scale_range_all_min_()) / (get_scale_label_value_() + 1);
            for(int i = 1; i <= get_scale_label_value_(); i++){
                QString str_i = QString::number(i * label_value_unit + get_scale_range_all_min_(), 'f', 0);
                map_label_points.insert(QPointF(rect_label.right() - i * label_pix - fm.horizontalAdvance(str_i) / 2,
                                                rect_label.bottom()), str_i);
            }
        }
    }

    painter->restore();

    // 绘制正常方向文字
    painter->save();
    for(auto it = map_label_points.begin(); it != map_label_points.end(); it++){
        auto p = getRotatePoint(translate_point_, it.key(), rotate_angle_);
        if(rotate_angle_ == 180.){
            p = getRotatePoint(translate_point_, it.key() -
                                QPointF(-fm.horizontalAdvance(it.value()), fm.height() / 2),
                                rotate_angle_);
        }
        if(rotate_angle_ == -90.){
            // QPointF::transposed() QT_VERSION >= 0x00050e00 (Qt 5.14.)
            if(it.key() == left_point){
                p = getRotatePoint(QPointF(translate_point_.y(), translate_point_.x()), it.key() +
                                   QPointF(0, - fm.horizontalAdvance(it.value())),
                                   rotate_angle_);
            } else if(it.key() == right_point){
                p = getRotatePoint(QPointF(translate_point_.y(), translate_point_.x()), it.key() +
                                   QPointF(fm.horizontalAdvance(it.value()) - fm.height() / 2.,
                                           -fm.horizontalAdvance(it.value())),
                                   rotate_angle_);
            } else {
                p = getRotatePoint(QPointF(translate_point_.y(), translate_point_.x()), it.key() +
                                   QPointF((fm.horizontalAdvance(it.value()) - fm.height() / 2.) / 2.,
                                           -fm.horizontalAdvance(it.value())),
                                   rotate_angle_);
            }
            if(get_scale_label_position_() == ScaleLabelPosition_Outside){
                // 左对齐
                p.setX(p.x() + fm.horizontalAdvance(it.value()) - fm.height());
            }
        }
        if(rotate_angle_ == 90.){
            // QPointF::transposed() QT_VERSION >= 0x00050e00 (Qt 5.14.)
            if(it.key() == left_point){
                p = getRotatePoint(QPointF(translate_point_.y(), translate_point_.x()), it.key() +
                                   QPointF(fm.height() / 2., 0),
                                   rotate_angle_);
            } else if(it.key() == right_point){
                p = getRotatePoint(QPointF(translate_point_.y(), translate_point_.x()), it.key() +
                                   QPointF(fm.horizontalAdvance(it.value()), 0),
                                   rotate_angle_);
            } else {
                p = getRotatePoint(QPointF(translate_point_.y(), translate_point_.x()), it.key() +
                                   QPointF((fm.horizontalAdvance(it.value()) + fm.height() / 2.) / 2.,
                                           0),
                                   rotate_angle_);
            }
            if(get_scale_label_position_() == ScaleLabelPosition_Outside){
                // 右对齐
                p.setX(p.x() - fm.horizontalAdvance(it.value()) + fm.height());
            }
        }
        painter->drawText(p, it.value());
    }
    painter->restore();
}

void QLsRuler::drawLine(QPainter *painter)
{
    if(get_ruler_type_() != RulerType_Line){
        return;
    }

    painter->save();
    painter->setPen(Qt::NoPen);

    QRect rect_all = getRotateRectAll(painter);

    // 从左到右
    if(get_scale_direction_() == ScaleDirection_Left_To_Right){
        // 绘制进度线条
        painter->setBrush(get_scale_range_valid_bgcolor_());
        painter->drawRect(
                    rect_all.left() + rect_all.width() *
                    (get_scale_value_() - get_scale_range_all_min_()) /
                    (get_scale_range_all_max_() - get_scale_range_all_min_()) -
                    (get_scale_label_size_().width() + 2) / 2,
                    0,
                    get_scale_label_size_().width() + 2,
                    rect_all.height()
                    );
    }
    // 从右到左
    else {
        // 绘制进度线条
        painter->setBrush(get_scale_range_valid_bgcolor_());
        painter->drawRect(
                    rect_all.left() + rect_all.width() *
                    (get_scale_range_all_max_() - get_scale_value_()) /
                    (get_scale_range_all_max_() - get_scale_range_all_min_()),
                    0,
                    get_scale_label_size_().width() + 2,
                    rect_all.height()
                    );
    }

    painter->restore();
}

void QLsRuler::drawCursor(QPainter *painter)
{
    // 游标标尺和滑动标尺都有游标
    if(!cursor_visiable_){
        return;
    }

    painter->save();
    painter->setPen(Qt::NoPen);

    QRect rect_scale = getRotateRectScale(painter);

    if(get_scale_label_position_() == ScaleLabelPosition_Outside){
        QPointF p;

        // 从左到右
        if(get_scale_direction_() == ScaleDirection_Left_To_Right){
            // 绘制游标
            p.setX(rect_scale.left() + rect_scale.width() *
                   (get_scale_value_() - get_scale_range_all_min_()) /
                   (get_scale_range_all_max_() - get_scale_range_all_min_()));
            p.setY(rect_scale.top() + get_scale_label_size_().height());
        }
        // 从右到左
        else {
            // 绘制游标
            p.setX(rect_scale.left() + rect_scale.width() *
                   (get_scale_range_all_max_() - get_scale_value_()) /
                   (get_scale_range_all_max_() - get_scale_range_all_min_()));
            p.setY(rect_scale.top() + get_scale_label_size_().height());
        }

        triangle_[0] = QPointF(p.x(), p.y() - sqrt(3) * get_cursor_side_() / 4);
        triangle_[1] = QPointF(p.x() - get_cursor_side_() / 2, p.y() + sqrt(3) * get_cursor_side_() / 4);
        triangle_[2] = QPointF(p.x() + get_cursor_side_() / 2, p.y() + sqrt(3) * get_cursor_side_() / 4);
        painter->setBrush(get_cursor_color_());
        painter->drawPolygon(triangle_);
    } else {
        QPointF p;

        // 从左到右
        if(get_scale_direction_() == ScaleDirection_Left_To_Right){
            // 绘制游标
            p.setX(rect_scale.left() + rect_scale.width() *
                   (get_scale_value_() - get_scale_range_all_min_()) /
                   (get_scale_range_all_max_() - get_scale_range_all_min_()));
            p.setY(rect_scale.top() - sqrt(3) * get_cursor_side_() / 4);
        }
        // 从右到左
        else {
            // 绘制游标
            p.setX(rect_scale.left() + rect_scale.width() *
                   (get_scale_range_all_max_() - get_scale_value_()) /
                   (get_scale_range_all_max_() - get_scale_range_all_min_()));
            p.setY(rect_scale.top() - sqrt(3) * get_cursor_side_() / 4);
        }

        triangle_[0] = QPointF(p.x(), p.y() + sqrt(3) * get_cursor_side_() / 4);
        triangle_[1] = QPointF(p.x() - get_cursor_side_() / 2, p.y() - sqrt(3) * get_cursor_side_() / 4);
        triangle_[2] = QPointF(p.x() + get_cursor_side_() / 2, p.y() - sqrt(3) * get_cursor_side_() / 4);
        painter->setBrush(get_cursor_color_());
        painter->drawPolygon(triangle_);
    }

    painter->restore();
}

QRect QLsRuler::getRotateRectAll(QPainter *painter)
{
    QRect rect_all = rect().adjusted(get_padding_left_(), get_padding_top_(), -get_padding_right_(), -get_padding_bottom_());

    switch (get_ruler_direction_()) {
    case RulerDirection_West:       // 上北
        translate_point_ = QPointF(0, 0);
        rotate_angle_ = 0;
        break;
    case RulerDirection_North:{     // 右东
        painter->translate(width(), 0);
        painter->rotate(90);
        auto w = rect_all.width();
        rect_all.setWidth(rect_all.height());
        rect_all.setHeight(w);
        translate_point_ = QPointF(width(), 0);
        rotate_angle_ = 90;
        break;
    }
    case RulerDirection_South:      // 下南
        painter->translate(width(), height());
        painter->rotate(180);
        translate_point_ = QPointF(width(), height());
        rotate_angle_ = 180;
        break;
    case RulerDirection_East:{       // 左西
        painter->translate(0, height());
        painter->rotate(-90);
        auto w = rect_all.width();
        rect_all.setWidth(rect_all.height());
        rect_all.setHeight(w);
        translate_point_ = QPointF(0, height());
        rotate_angle_ = -90;
        break;
    }
    default: break;
    }

    return rect_all;
}

QRect QLsRuler::getRotateRectTrue(QPainter *painter)
{
    QRect rect_all = getRotateRectAll(painter);
    QFontMetrics fm(font());

    // 获取刻度条区域 默认刻度条区域居中
    auto h = (!get_scale_label_visiable_() ? 0 : fm.height() + get_scale_label_space_()) +
            get_scale_label_size_().height() + get_scale_thickness_();
    return QRect(rect_all.left(), rect_all.top() + (rect_all.height() - h) / 2,
                 rect_all.width(), h);
}

QRect QLsRuler::getRotateRectScale(QPainter *painter)
{
    QRect rect_true = getRotateRectTrue(painter);
    QFontMetrics fm(font());

    QRect rect_scale;
    if(scale_label_position_ == ScaleLabelPosition_Inside){
        rect_scale = rect_true.adjusted(
                    0, (!get_scale_label_visiable_()
                        ? 0 : fm.height() + get_scale_label_space_()),
                    0, 0);
    } else {
        rect_scale = rect_true.adjusted(
                    0, 0, 0,
                    -((!get_scale_label_visiable_()
                       ? 0 : fm.height() + get_scale_label_space_())));
    }

    return rect_scale;
}

QRect QLsRuler::getRotateRectLabel(QPainter *painter)
{
    QRect rect_true = getRotateRectTrue(painter);

    QRect rect_label;
    if(scale_label_position_ == ScaleLabelPosition_Inside){
        rect_label = rect_true.adjusted(0, 0, 0, -(get_scale_label_space_() + get_scale_label_size_().height() +
                                                   get_scale_thickness_()));
    } else {
        rect_label = rect_true.adjusted(0, get_scale_label_space_() + get_scale_label_size_().height() +
                                        get_scale_thickness_(), 0, 0);
    }

    return rect_label;
}

QPointF QLsRuler::getRotatePoint(const QPointF &p0, const QPointF &p1, double a)
{
    auto p = p0 - p1;
    p.setX(qFabs(p.x()));
    p.setY(qFabs(p.y()));

    if(qFabs(a) == 90){
        // QPointF::transposed() QT_VERSION >= 0x00050e00 (Qt 5.14.)
        return QPointF(p.y(), p.x());
    }
    return p;
}
